/**
 * @file test_database.cpp
 * @brief 数据库层功能测试
 * @author liyingcheng <1871304538@qq.com>
 * @date 2025-10-12
 */

#include "database/database_config.h"
#include "database/mysql_pool.h"
#include "database/mysql_orm.h"
#include "database/database_health.h"
#include "LoggerManager.h"
#include <iostream>
#include <iomanip>

using namespace cpp_backend::database;
using namespace logger;

// ============================================
// 测试辅助函数
// ============================================

void PrintSeparator(const std::string &title = "")
{
    std::cout << "\n";
    std::cout << "============================================\n";
    if (!title.empty())
    {
        std::cout << " " << title << "\n";
        std::cout << "============================================\n";
    }
}

void PrintResult(const std::string &test_name, bool success)
{
    std::cout << std::left << std::setw(40) << test_name << ": "
              << (success ? "\033[32m✓ PASSED\033[0m" : "\033[31m✗ FAILED\033[0m")
              << "\n";
}

// ============================================
// 测试1: 配置管理
// ============================================

bool TestConfigManagement()
{
    PrintSeparator("Test 1: 配置管理");

    try
    {
        // 1. 先加载全局配置（从config模块）
        auto &global_config = cpp_backend::config::Config::Instance();
        if (!global_config.LoadFromFile("config/server.json"))
        {
            std::cout << "警告: 无法加载config/server.json，使用默认配置\n";
        }

        // 2. 将全局配置应用到数据库模块
        auto &db_config = DatabaseConfig::Instance();
        if (!db_config.ApplyConfig(global_config))
        {
            std::cout << "错误: 应用数据库配置失败\n";
            PrintResult("配置管理测试", false);
            return false;
        }

        std::cout << "\n数据库配置:\n";
        std::cout << db_config.ToString() << "\n";

        // 3. 验证配置
        bool valid = db_config.ValidateConfig();

        PrintResult("配置加载和验证", valid);
        return valid;
    }
    catch (const std::exception &e)
    {
        std::cout << "异常: " << e.what() << "\n";
        PrintResult("配置管理测试", false);
        return false;
    }
}

// ============================================
// 测试2: MySQL连接池
// ============================================

bool TestMySQLConnectionPool()
{
    PrintSeparator("Test 2: MySQL连接池");

    try
    {
        auto &config = DatabaseConfig::Instance();
        const auto &mysql_cfg = config.GetMySQLConfig();

        // 初始化连接池
        std::cout << "初始化MySQL连接池...\n";
        bool init_ok = MySQLPool::Instance().Initialize(
            mysql_cfg.host,
            mysql_cfg.port,
            mysql_cfg.database,
            mysql_cfg.username,
            mysql_cfg.password,
            mysql_cfg.pool_size);

        if (!init_ok)
        {
            PrintResult("连接池初始化", false);
            return false;
        }

        PrintResult("连接池初始化", true);

        // 获取连接池统计
        auto stats = MySQLPool::Instance().GetStats();
        std::cout << "\n连接池统计:\n";
        std::cout << "  总连接数: " << stats.total_connections << "\n";
        std::cout << "  可用连接: " << stats.available_connections << "\n";
        std::cout << "  活跃连接: " << stats.active_connections << "\n";

        // 测试获取连接
        std::cout << "\n测试获取连接...\n";
        MySQLConnectionGuard guard(3000);
        bool conn_ok = guard.IsValid();

        PrintResult("获取MySQL连接", conn_ok);

        if (conn_ok)
        {
            // 执行简单查询
            try
            {
                std::unique_ptr<sql::Statement> stmt(guard->createStatement());
                std::unique_ptr<sql::ResultSet> res(stmt->executeQuery("SELECT VERSION() as version"));

                if (res && res->next())
                {
                    std::string version = res->getString("version");
                    std::cout << "MySQL版本: " << version << "\n";
                    PrintResult("执行查询", true);
                }
                else
                {
                    PrintResult("执行查询", false);
                }
            }
            catch (const std::exception &e)
            {
                std::cout << "查询异常: " << e.what() << "\n";
                PrintResult("执行查询", false);
                return false;
            }
        }

        return conn_ok;
    }
    catch (const std::exception &e)
    {
        std::cout << "异常: " << e.what() << "\n";
        PrintResult("MySQL连接池测试", false);
        return false;
    }
}

// ============================================
// 测试3: MySQL ORM操作
// ============================================

bool TestMySQLORM()
{
    PrintSeparator("Test 3: MySQL ORM操作");

    try
    {
        // 创建测试表
        std::cout << "创建测试表...\n";
        MySQLConnectionGuard guard(3000);
        if (!guard.IsValid())
        {
            PrintResult("获取连接", false);
            return false;
        }

        // 删除旧表（如果存在）
        try
        {
            std::unique_ptr<sql::Statement> stmt(guard->createStatement());
            stmt->execute("DROP TABLE IF EXISTS test_users");
        }
        catch (...)
        {
        }

        // 创建新表
        std::unique_ptr<sql::Statement> stmt(guard->createStatement());
        stmt->execute(
            "CREATE TABLE test_users ("
            "  id INT AUTO_INCREMENT PRIMARY KEY,"
            "  name VARCHAR(100) NOT NULL,"
            "  email VARCHAR(100) NOT NULL,"
            "  age INT,"
            "  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
            ")");
        PrintResult("创建测试表", true);

        // 测试插入
        std::cout << "\n测试插入记录...\n";
        nlohmann::json user1 = {
            {"name", "张三"},
            {"email", "zhangsan@example.com"},
            {"age", 25}};

        int64_t id1 = MySQLORM::Insert("test_users", user1);
        bool insert_ok = (id1 > 0);
        PrintResult("插入单条记录", insert_ok);
        if (insert_ok)
        {
            std::cout << "  插入ID: " << id1 << "\n";
        }

        // 测试批量插入
        std::cout << "\n测试批量插入...\n";
        nlohmann::json users = nlohmann::json::array({{{"name", "李四"}, {"email", "lisi@example.com"}, {"age", 30}},
                                                      {{"name", "王五"}, {"email", "wangwu@example.com"}, {"age", 28}}});

        int batch_count = MySQLORM::BatchInsert("test_users", users);
        bool batch_ok = (batch_count == 2);
        PrintResult("批量插入记录", batch_ok);
        if (batch_ok)
        {
            std::cout << "  插入数量: " << batch_count << "\n";
        }

        // 测试查询
        std::cout << "\n测试查询记录...\n";
        auto all_users = MySQLORM::FindAll("test_users");
        bool find_ok = (all_users.is_array() && all_users.size() == 3);
        PrintResult("查询所有记录", find_ok);
        if (find_ok)
        {
            std::cout << "  记录数: " << all_users.size() << "\n";
            std::cout << "  数据: " << all_users.dump(2) << "\n";
        }

        // 测试根据ID查询
        std::cout << "\n测试根据ID查询...\n";
        auto user = MySQLORM::FindById("test_users", id1);
        bool find_by_id_ok = (!user.is_null() && user["name"] == "张三");
        PrintResult("根据ID查询", find_by_id_ok);

        // 测试更新
        std::cout << "\n测试更新记录...\n";
        nlohmann::json update_data = {{"age", 26}};
        int update_count = MySQLORM::UpdateById("test_users", id1, update_data);
        bool update_ok = (update_count == 1);
        PrintResult("更新记录", update_ok);

        // 测试统计
        std::cout << "\n测试统计记录数...\n";
        int64_t count = MySQLORM::Count("test_users");
        std::cout << "  返回的count值: " << count << "\n";
        bool count_ok = (count == 3);
        PrintResult("统计记录数", count_ok);
        if (count_ok)
        {
            std::cout << "  总记录数: " << count << "\n";
        }
        else
        {
            std::cout << "  期望: 3, 实际: " << count << "\n";
        }

        // 测试分页查询
        std::cout << "\n测试分页查询...\n";
        auto page_result = MySQLORM::Paginate("test_users", 1, 2);
        std::cout << "  分页结果: " << page_result.dump(2) << "\n";
        bool page_ok = (!page_result.empty() &&
                        page_result.contains("data") &&
                        page_result["data"].size() == 2 &&
                        page_result.contains("pagination") &&
                        page_result["pagination"]["total"] == 3);
        PrintResult("分页查询", page_ok);
        if (page_ok)
        {
            std::cout << "  分页信息: " << page_result["pagination"].dump(2) << "\n";
        }
        else if (!page_result.empty())
        {
            std::cout << "  期望data.size=2, total=3\n";
            if (page_result.contains("data"))
            {
                std::cout << "  实际data.size=" << page_result["data"].size() << "\n";
            }
            if (page_result.contains("pagination"))
            {
                std::cout << "  实际total=" << page_result["pagination"]["total"] << "\n";
            }
        }

        // 测试删除
        std::cout << "\n测试删除记录...\n";
        int delete_count = MySQLORM::DeleteById("test_users", id1);
        bool delete_ok = (delete_count == 1);
        PrintResult("删除记录", delete_ok);

        // 清理测试表
        stmt->execute("DROP TABLE test_users");

        return insert_ok && batch_ok && find_ok && find_by_id_ok &&
               update_ok && count_ok && page_ok && delete_ok;
    }
    catch (const std::exception &e)
    {
        std::cout << "异常: " << e.what() << "\n";
        PrintResult("MySQL ORM测试", false);
        return false;
    }
}

// ============================================
// 测试4: 健康检查
// ============================================

bool TestHealthCheck()
{
    PrintSeparator("Test 4: 数据库健康检查");

    try
    {
        auto &checker = DatabaseHealthChecker::Instance();

        // 检查MySQL
        std::cout << "检查MySQL健康状态...\n";
        auto mysql_health = checker.CheckMySQL();
        std::cout << "MySQL健康检查结果:\n";
        std::cout << mysql_health.ToJson().dump(2) << "\n";
        PrintResult("MySQL健康检查", mysql_health.IsHealthy());

        // 检查所有数据库
        std::cout << "\n检查所有数据库健康状态...\n";
        auto all_health = checker.CheckAll();
        std::cout << "总体健康检查结果:\n";
        std::cout << all_health.ToJson().dump(2) << "\n";
        PrintResult("总体健康检查", all_health.IsHealthy());

        return mysql_health.IsHealthy();
    }
    catch (const std::exception &e)
    {
        std::cout << "异常: " << e.what() << "\n";
        PrintResult("健康检查测试", false);
        return false;
    }
}

// ============================================
// 主测试函数
// ============================================

int main(int argc, char *argv[])
{
    // 初始化日志
    LogConfig config;
    config.moduleName = "database_test";
    config.logDirectory = "logs";
    config.minLevel = LogLevel::DEBUG_LEVEL;
    config.asyncMode = false; // 测试时使用同步模式
    config.consoleOutput = true;
    LoggerManager::getInstance().init(config);

    PrintSeparator("数据库层功能测试");

    std::cout << "\n开始测试...\n";

    int passed = 0;
    int failed = 0;

    // 运行测试
    if (TestConfigManagement())
        passed++;
    else
        failed++;
    if (TestMySQLConnectionPool())
        passed++;
    else
        failed++;
    if (TestMySQLORM())
        passed++;
    else
        failed++;
    if (TestHealthCheck())
        passed++;
    else
        failed++;

    // 输出结果
    PrintSeparator("测试结果汇总");
    std::cout << "\n";
    std::cout << "通过: \033[32m" << passed << "\033[0m\n";
    std::cout << "失败: " << (failed > 0 ? "\033[31m" : "") << failed << (failed > 0 ? "\033[0m" : "") << "\n";
    std::cout << "总计: " << (passed + failed) << "\n";
    std::cout << "\n";

    if (failed == 0)
    {
        std::cout << "\033[32m✓ 所有测试通过！\033[0m\n";
    }
    else
    {
        std::cout << "\033[31m✗ 部分测试失败\033[0m\n";
    }

    PrintSeparator();

    return failed == 0 ? 0 : 1;
}
